package com.zhuoyue.web.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zhuoyue.biz.core.api.domain.*;
import com.zhuoyue.biz.core.api.dto.rep.GatewayRepDTO;
import com.zhuoyue.biz.core.api.dto.req.GateWayDTO;
import com.zhuoyue.biz.core.api.service.AutomateService;
import com.zhuoyue.biz.core.api.service.GatewayRedisService;
import com.zhuoyue.biz.core.api.service.GatewayService;
import com.zhuoyue.biz.core.api.service.impl.GatewayTimingSceneService;
import com.zhuoyue.biz.core.api.service.impl.LocalSceneService;
import com.zhuoyue.biz.core.api.service.impl.ProductInfoAppService;
import com.zhuoyue.common.aop.auth.CheckLogin;
import com.zhuoyue.common.aop.auth.User;
import com.zhuoyue.common.dto.ControllerResult;
import com.zhuoyue.common.group.ValidationGroups;
import com.zhuoyue.common.utils.Time;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.validator.constraints.Length;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;


import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotBlank;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author wjming
 * @ClassName: AppGatewayController
 * @Description:网关设备操作接口
 * @Date 2021/4/16 11:49
 */
@RestController
@Scope("prototype")
@RequestMapping("/api/gateway")
@Validated
@Slf4j(topic = "GatewayController")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class AppGatewayController {
    private final GatewayService gatewayService;
    private final LocalSceneService localSceneService;
    private final AutomateService automateService;
    private final GatewayTimingSceneService gatewayTimingSceneService;
    private final GatewayRedisService gatewayRedisService;
    private final ProductInfoAppService productInfoAppService;

    /**
     * @Description:查询家庭中的网关列表
     * @param: homeId
     * @return: com.zhuoyue.common.dto.ControllerResult
     * @author:wjming
     * @Date:2021/4/16 11:51
     */
    @GetMapping("/list")
    @CheckLogin
    public ControllerResult getGatewayList(@NotBlank(message = "家庭ID不能为空") String homeId) {
        List<GatewayRepDTO> gatewayRepS = gatewayService.getGatewayMessages(homeId);
        return ControllerResult.toReturnDataSuccess("查询成功", gatewayRepS);
    }


    /**
     * 新增网关
     * 已废弃新网关模糊搜索的功能
     *
     * @param gateWayDTO
     * @return
     */
    @PostMapping("/add")
    @CheckLogin
    public ControllerResult addGateway(@Validated(ValidationGroups.Insert.class) @RequestBody GateWayDTO gateWayDTO, HttpServletRequest request) {
        User user = (User) request.getAttribute("user");
        log.info("request -> user:[{}_{}] [addGateway] -> [gateWayDTO:{}]", user.getAccount(), user.getOrgCode(), JSONObject.toJSONString(gateWayDTO));

        GatewayDO gateway = new GatewayDO();
        BeanUtils.copyProperties(gateWayDTO, gateway);

        String gatewayMac = gateWayDTO.getZigbeeMac();
        QueryWrapper<LocalSceneDO> queryWrapper1 = new QueryWrapper();
        queryWrapper1.eq("gateway_mac", gatewayMac);
        int count = localSceneService.count(queryWrapper1);

        if (count < 1) {
            QueryWrapper<LocalSceneDO> queryWrapper2 = new QueryWrapper();
            queryWrapper2.eq("home_id", gateWayDTO.getHomeId());
            List<LocalSceneDO> list1 = localSceneService.list(queryWrapper2);
            //先根据homeId找到对应的场景信息，再逐条改变其gatewayMac
            for (LocalSceneDO localSceneDO : list1) {
                if (StringUtils.isEmpty(localSceneDO.getGatewayMac())) {
                    LocalSceneDO localSceneDo1 = new LocalSceneDO();
                    localSceneDo1 = localSceneDO;
                    localSceneDo1.setGatewayMac(gateWayDTO.getZigbeeMac());
                    localSceneService.updateById(localSceneDo1);
                }
            }
        } else {
            //删除该网关老场景
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("home_id", gateWayDTO.getHomeId());

            localSceneService.remove(queryWrapper);
        }
        GatewayRepDTO gatewayRepDTO = gatewayService.addGateway(gateway);
        log.info("result -> [addGateway] -> [gatewayRepDTO:{}]", gatewayRepDTO);
        return ControllerResult.toReturnDataSuccess("添加成功", gatewayRepDTO);
    }


    /**
     * 新网关（铂金网关）专用
     *
     * @param zigbeeMac 网关mac地址
     * @return
     */
    @GetMapping("/getMac")
    @CheckLogin
    public ControllerResult getGatewayMac(@NotBlank(message = "网关MAC地址不能为空！") String zigbeeMac) {

        GatewayDO one = gatewayService.getOne(Wrappers.<GatewayDO>lambdaQuery()
                .like(GatewayDO::getZigbeeMac, zigbeeMac));
        if (null == one) {
            return ControllerResult.toParamFail("铂金网关不存在");
        }
        return ControllerResult.toReturnDataSuccess("获取成功", one.getZigbeeMac());
    }

    /**
     * 修改网关
     * 根据网关ID修改网关信息
     *
     * @param gateWayDTO
     * @return
     */
    @PutMapping("/modify")
    @CheckLogin
    public ControllerResult updateGatewayById(@Validated(ValidationGroups.Update.class) GateWayDTO gateWayDTO) {
        GatewayDO gateway = new GatewayDO();
        BeanUtils.copyProperties(gateWayDTO, gateway);
        gateway.setId(gateWayDTO.getGatewayId());

        GatewayDO gatewayDO = gatewayService.updateGatewayById(gateway);
        List<String> deviceFun = productInfoAppService.getDeviceFun(gatewayDO.getProdId());
        GatewayRepDTO gatewayRepDTO = new GatewayRepDTO().gatewayDoToDto(gatewayDO, deviceFun);
        return ControllerResult.toReturnDataSuccess("修改成功", gatewayRepDTO);
    }

    /**
     * 删除网关
     */

    @DeleteMapping("/delete")
    @CheckLogin
    public ControllerResult deleteGatewayById(@RequestParam String gatewayId, HttpServletRequest request) {
        User user = (User) request.getAttribute("user");
        log.info("request -> user:[{}_{}] [deleteGatewayById] -> [gatewayId:{}]", user.getAccount(), user.getOrgCode(), gatewayId);
        gatewayService.deleteGatewayById(gatewayId);
        return ControllerResult.toReturnMessageSuccess("删除成功");
    }


    /**
     * 解绑网关
     *
     * @return
     */
    @DeleteMapping("/deleteGateway")
    @CheckLogin
    public ControllerResult unboundGateway(HttpServletRequest request, @NotBlank(message = "网关ID不能为空") String gatewayId) {
        User user = (User) request.getAttribute("user");
        log.info("request -> user:[{}_{}] [unboundGateway] -> [gatewayId:{}]", user.getAccount(), user.getOrgCode(), gatewayId);
        gatewayService.unbindGatewayById(gatewayId);
        return ControllerResult.toReturnMessageSuccess("成功");
    }

    /**
     * 清空网关下的场景、自动化、网关定时任务
     *
     * @return
     */
    @PostMapping("/clear")
    @CheckLogin
    public ControllerResult clearGateway(String homeId) throws InterruptedException {

        //根据homeId查询网关信息
        GatewayDO gatewayDO = gatewayService.getByHomeId(homeId);
        if (gatewayDO == null) {
            return ControllerResult.toParamFail("请先添加网关");
        }

        String gatewayMac = gatewayDO.getZigbeeMac();

        //删除场景、自动化、网关定时任务
        localSceneService.remove(Wrappers.<LocalSceneDO>lambdaQuery().eq(LocalSceneDO::getHomeId, homeId));
        automateService.remove(Wrappers.<AutomateDO>lambdaQuery().eq(AutomateDO::getHomeId, homeId));
        gatewayTimingSceneService.remove(Wrappers.<GatewayTimingScene>lambdaQuery().eq(GatewayTimingScene::getGatewayId, gatewayDO.getId()));

        //网关恢复出厂设置
        String clearGatewayFrame = gatewayService.clearGatewayFrame(gatewayMac);
        gatewayRedisService.writeDataToGateway(gatewayMac, clearGatewayFrame);

        Thread.sleep(300);

        //网关重置
        String resetGatewayFrame = gatewayService.resetGatewayFrame(gatewayMac);
        gatewayRedisService.writeDataToGateway(gatewayMac, resetGatewayFrame);

        return ControllerResult.toReturnDataSuccess("命令发送成功", null);
    }
}
